/**
    Copyright (c) 2010 yakiimo02
    Distributed under the New BSD License.
    See included license.txt or http://www.yakiimo3d.com/NewBSDLicense.txt
**/

#pragma once

/**
    @brief  Measure log avg luminance and max luminance using compute shaders.
    @author yakiimo02
    @date   2010/02/15
*/
class MeasureLuminanceCS
{
public:
    MeasureLuminanceCS();
    ~MeasureLuminanceCS();

    HRESULT OnCreateDevice( ID3D11Device* pd3dDevice );
    HRESULT OnResizedSwapChain( ID3D11Device* pd3dDevice, const int nWidth, const int nHeight );
    void    OnDestroyDevice();
    void    OnReleasingSwapChain();

    HRESULT DoMeasureLuminance( ID3D11DeviceContext* pd3dImmediateContext, int nWidth, int nHeight, ID3D11ShaderResourceView* pInputSRV );

    inline ID3D11ShaderResourceView*    GetpReductionRV1() { return m_pReductionRV1; }

    inline float GetLogAvgLum() const { return m_fLogAvgLum; }
    inline float GetLumMax() const { return m_fLumMax; }

protected:
    HRESULT CompileShaders( ID3D11Device* pd3dDevice );
    void    RunComputeShader( ID3D11DeviceContext* pd3dImmediateContext,
                              ID3D11ComputeShader* pComputeShader,    
                              UINT nNumViews, ID3D11ShaderResourceView** pShaderResourceViews, 
                              ID3D11Buffer* pCBCS, void* pCSData, DWORD dwNumDataBytes,
                              ID3D11UnorderedAccessView* pUnorderedAccessView,
                              UINT X, UINT Y, UINT Z );

protected:
    // compute shaders
    ID3D11ComputeShader*        m_pReduceTo1DCS;
    ID3D11ComputeShader*        m_pReduceToSingleCS;

    // Two StructuredBuffer used for ping-ponging in the CS reduction operation
    ID3D11Buffer*               m_pBufferReduction0;
    ID3D11Buffer*               m_pBufferReduction1;

    // SRV
    ID3D11ShaderResourceView*   m_pReductionRV0;
    ID3D11ShaderResourceView*   m_pReductionRV1;

    // UAV
    ID3D11UnorderedAccessView*  m_pReductionUAView0;
    ID3D11UnorderedAccessView*  m_pReductionUAView1;

    // Constant buffer for passing parameters into the CS
    ID3D11Buffer*               m_pcbCS;

    int                         m_nReduceTo1DX_;
    int                         m_nReduceTo1DY_;

    ID3D11Buffer*               m_pGPUtoCPUBuf;

    float                       m_fLogAvgLum;            // log average luminance
    float                       m_fLumMax;               // luminance max value
};
